#ifndef OBJVIEWERWIDGET_H
#define OBJVIEWERWIDGET_H

#include <QOpenGLWidget>
#include <QOpenGLFunctions>
#include <QOpenGLShaderProgram>
#include <QOpenGLBuffer>
#include <QOpenGLVertexArrayObject>
#include <QOpenGLTexture>
#include <QMatrix4x4>
#include <QVector3D>
#include <QQuaternion>
#include <QMouseEvent>
#include <QWheelEvent>

struct Vertex {
    QVector3D position;
    QVector3D normal;
    QVector2D texCoord;
};

class ObjViewerWidget : public QOpenGLWidget, protected QOpenGLFunctions
{
    Q_OBJECT

public:
    explicit ObjViewerWidget(QWidget *parent = nullptr);
    ~ObjViewerWidget();

    void loadModel(const QString &filePath);

protected:
    void initializeGL() override;
    void resizeGL(int w, int h) override;
    void paintGL() override;

    void mousePressEvent(QMouseEvent *event) override;
    void mouseMoveEvent(QMouseEvent *event) override;
    void wheelEvent(QWheelEvent *event) override;

private:
    bool loadOBJ(const QString &filePath);
    bool loadTexture(const QString &filePath);
    void setupShader();
    void calculateNormals(QVector<Vertex> &vertices);
    void updateVertexBuffer();

    QOpenGLShaderProgram *shaderProgram;
    QOpenGLBuffer vbo;
    QOpenGLVertexArrayObject vao;
    QOpenGLTexture *texture;

    QVector<Vertex> vertices;
    QVector<unsigned int> indices;

    QMatrix4x4 projection;
    QMatrix4x4 view;
    QMatrix4x4 model;

    QVector3D cameraPosition;
    QVector3D cameraTarget;
    QVector3D cameraUp;

    float cameraDistance;
    QPoint lastMousePos;
    QQuaternion rotation;

    bool modelLoaded;
    bool textureLoaded;
};

#endif // OBJVIEWERWIDGET_H
